package model1

import "fmt"

/*

Go语言中目前（Go1.12）是没有异常机制，
但是使用panic/recover模式来处理错误。
panic可以在任何地方引发，
但recover只有在defer调用的函数中有效。
首先来看一个例子：

*/
func funcA() {
	fmt.Println("func A")
}

func funcB() {
	panic("panic in B")
}

func funcC() {
	fmt.Println("func C")
}
func TestPanic() {
	funcA()
	funcB()
	funcC()
	/*
		func A
		panic: panic in B

		goroutine 1 [running]:
		function/model1.funcB(...)
		        D:/LearnProject/GoLang/my-golang-learning-warehouse/Go语言基础之函数/model1/panicAndRecover.go:19
		function/model1.TestPanic()
		        D:/LearnProject/GoLang/my-golang-learning-warehouse/Go语言基础之函数/model1/panicAndRecover.go:27 +0x66
		main.main()
		        D:/LearnProject/GoLang/my-golang-learning-warehouse/Go语言基础之函数/main.go:49 +0x57
		exit status 2
	*/
	/*
	   程序运行期间funcB中引发了panic导致程序崩溃，异常退出了。
	   这个时候我们就可以通过recover将程序恢复回来，继续往后执行。
	*/
}

func funcA1() {
	fmt.Println("func A")
}

func funcB1() {
	defer func() {
		err := recover()
		//如果程序出出现了panic错误,可以通过recover恢复过来
		if err != nil {
			fmt.Println("recover in B")
		}
	}()
	panic("panic in B")
}

func funcC1() {
	fmt.Println("func C")
}
func TestPanicAndRecover() {
	funcA1()
	funcB1()
	funcC1()
	/*
		注意：
			recover()必须搭配defer使用。
			defer一定要在可能引发panic的语句之前定义。
	*/
}
